package com.jamila.basestation.main;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jamila.basestation.entity.BaseStationInfo;
import com.jamila.basestation.entity.Bsd;
import com.jamila.basestation.mapper.BaseStationInfoMapper;
import com.jamila.basestation.mapper.BsdMapper;
import com.jamila.basestation.tool.AddressResolutionUtil;
import com.jamila.basestation.tool.HttpClientUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Description: 定时执行任务
 * @CreateTime: 2023-12-04  10:27
 * @Author: JAMILA
 * @Version: 1.0
 */

@Component // 把此类托管给 Spring，不能省略
public class Task {
    @Autowired
    private BaseStationInfoMapper baseStationInfoMapper;

    @Autowired
    private BsdMapper bsdMapper;



    /**
     * 限制条件：每5分钟限制查询300次，单基站/单WIFI/经纬度查询接口每日限制查询1000次
     * http://api.cellocation.com:84/cell/?mcc=460&mnc=1&lac=38001&ci=65535&output=json

     * 1.从bsd表中获取LAC+CID
     * 2.通过LAC+CID访问第三方接口（mnc=1/mnc=0）
     * 3.若存在数据则保存至base_station_info表中
     */
    //每天晚上23:00:00定时执行访问第三方基站接口，将数据保存至本地数据库中
    @Scheduled(cron = "0 0 23 * * ?")
    public void mianTask() throws ParseException {



        String LAC = "";
        String CID = "";
        int count = 0;//总次数
        int successTime = 0;//成功次数
        int failTime = 0;//失败次数

        //获取基站总数量
        Integer bsdCount = bsdMapper.selectCount(null);


        //计算相差天数
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        Date d1= null;
        try {
            d1 = sdf.parse("2023-12-01 00:00:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int taskTime = daysBetween(d1, new Date());


        QueryWrapper<Bsd> wrapper = new QueryWrapper<>();
        String sql="limit "+(bsdCount-taskTime*1000)+",1000";
        wrapper.last(sql);
        List<Bsd> bsds = bsdMapper.selectList(wrapper);

        System.out.println("-----------本次操作开始时间："+new Date()+"---startIndex:"+(bsdCount-taskTime*1000)+"----------");
        for (Bsd b : bsds) {

            LAC = b.getArea();
            CID = b.getCell();
            JSONObject address = getAddress(LAC, CID);

            //如果address为空 则说第三方接口明今日访问次数已使用完
            if (address==null){
                System.out.println("今日1000次访问次数完毕。总访问次数："+count+"，成功次数："+successTime+",失败次数："+failTime);
                System.out.println("-----------本次操作结束时间："+new Date()+"-------------");
                return;
            }


            if ("0".equals(address.getString("errcode"))) {
                BaseStationInfo baseStationInfo = new BaseStationInfo();
                baseStationInfo.setLac(Long.valueOf(LAC));
                baseStationInfo.setCid(Long.valueOf(CID));
                baseStationInfo.setLon(Double.parseDouble(address.getString("lon")));
                baseStationInfo.setLat(Double.parseDouble(address.getString("lat")));
                baseStationInfo.setRadius(Double.parseDouble(address.getString("radius")));
                baseStationInfo.setAddress(address.getString("address"));
                //从地址字符串中解析出省、市、县/区
                Map<String, String> map = AddressResolutionUtil.addressResolutionPlus(address.getString("address"));
                if (!map.isEmpty()) {
                    baseStationInfo.setProvince(map.get("province"));
                    baseStationInfo.setCity(map.get("city"));
                    baseStationInfo.setCounty(map.get("county"));
                }
                baseStationInfoMapper.insert(baseStationInfo);
                successTime++;
                System.out.println("第" + count + "次访问，获取地址成功！ LAC："+ LAC + " CID:" + CID +" 位置信息："+ address.getString("address"));

            } else {
                //基站定位第三方接口访问出错，非国内位置
                failTime++;
                System.out.println("第" + count + "次访问，获取地址失败！ LAC："+ LAC + " CID:" + CID);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            count++;

        }

        System.out.println("-----------本次操作结束时间："+new Date()+"-------------");
    }


    //访问第三方接口获取相关信息-http://api.cellocation.com:84/cell/?mcc=460&mnc=1&lac=30598&ci=126348545&output=json
    private JSONObject getAddress(String lac, String cid){
        //通过LAC+CID获取地址信息
        String requestUrl = "http://api.cellocation.com:84/cell/?mcc=460&mnc=1&lac="+lac+"&ci="+cid+"&output=json";
        JSONObject jsonObject = JSON.parseObject(HttpClientUtil.doGet(requestUrl));

        //如果返回结果为10001，说明无查询结果，更换mnc为0再次查询结果
        if (jsonObject!=null&&"10001".equals(jsonObject.getString("errcode"))){
            requestUrl = "http://api.cellocation.com:84/cell/?mcc=460&mnc=0&lac="+lac+"&ci="+cid+"&output=json";
            jsonObject = JSON.parseObject(HttpClientUtil.doGet(requestUrl));
        }

        return jsonObject;
    }

    /**
     * 计算两个日期之间相差的天数
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    private int daysBetween(Date smdate,Date bdate) throws ParseException
    {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        smdate=sdf.parse(sdf.format(smdate));
        bdate=sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }





}
